﻿using System;
using System.Linq;
using System.Data.Linq;
using BusinessLogic;
using BusinessLogic.Model;
using BusinessLogic.Model.Repository;
using BusinessLogic.Model.Repository.NewsItemRepositories;
using BusinessLogic.StateManagers;
using BusinessLogic.Model.Repository.CommentsRepositories;
using System.Collections;

namespace Mvp.NewsItems
{
    public class ViewNewsItemPresenter : Presenter<IViewNewsItemView>
    {
        private INewsItemRepository Repository { get; set; }
        private ICommentRepository CommentRepository { get; set; }

        public ViewNewsItemPresenter(IViewNewsItemView view)
            : base(view)
        {
        }

        public void Init()
        {
            Repository = RepositoryFactory.Instance.GetNewsItemRepository();
            NewsItem newsItem = Repository.Get(View.NewsItemID);
            if (newsItem == null)
            {
                SessionManager.ErrorMessage = ErrorConstants.ArticleNotFound;
                Context.Server.Transfer("~/Error.aspx");
            }
            else
            {
                View.NewsItem = newsItem;
            }

            string commentsPageSize = ApplicationManager.CommentsPageSize;
            View.CommentsPageSize = String.IsNullOrEmpty(commentsPageSize) ? SettingsDefaults.CommentsPageSize : Convert.ToInt32(commentsPageSize);
        }

        public void Load()
        {
            switch (View.NewsItem.AllowComments)
            {
                case CommentsPolicy.Everyone:
                    {
                        View.CommentsEnabled = true;
                    }
                    break;
                case CommentsPolicy.Registered:
                    {
                        if (User.Identity.IsAuthenticated)
                        {
                            View.CommentsEnabled = true;
                        }
                        else
                        {
                            View.CommentsEnabled = false;
                            View.CommentsStatusText = "You must log in to post comments on this article";
                        }
                    }
                    break;
                case CommentsPolicy.Forbidden:
                    {
                        View.CommentsEnabled = false;
                        View.CommentsStatusText = "Comments on this article are disabled";
                    }
                    break;
            }
        }

        public void SaveComment()
        {
            string username;

            int newLineCount = 0;

            string commentText = View.NewCommentText;
            //max length of message is 10001 and I don't care that it should be in config
            if (commentText.Length > 10001)
            {
                SessionManager.ErrorMessage = ErrorConstants.InvalidCommentLength;
                Context.Server.Transfer("~/Error.aspx");
            }
            else
            {
                foreach (char c in commentText)
                {
                    if (c == '\n') newLineCount++;
                }

                //max number of new lines is 51
                if (newLineCount > 51)
                {
                    SessionManager.ErrorMessage = ErrorConstants.InvalidCommentLength;
                    Context.Server.Transfer("~/Error.aspx");
                }
            }

            if (User.Identity.IsAuthenticated)
            {
                username = User.Identity.Name;
            }
            else
            {
                View.ValidateCaptcha();
                string textBoxUsername = View.GuestUsername.Trim();
                username = (textBoxUsername == "" ? "Guest" : textBoxUsername.HtmlEncode()) + " (Unregistered)";
            }

            Comment newComment = new Comment
            {
                AuthorUsername = username,
                PostDate = DateTime.Now,
                NewsItemID = View.NewsItem.NewsItemID,
                NewsItem = View.NewsItem,
                Text = commentText.HtmlEncode().ReplaceUrlsWithLinks().TrimEnd(null).Replace("  ", " &nbsp;").Replace(Environment.NewLine, "<br />"),
                IPAddress = Context.Request.UserHostAddress
            };

            CommentRepository = RepositoryFactory.Instance.GetCommentRepository();
            CommentRepository.Create(newComment);

            int pageNumber = (View.NewsItem.Comments.Count() - 1) / View.CommentsPageSize + 1;

            Context.Response.Redirect(UrlUtilities.GenerateCommentUrl(newComment, pageNumber));
        }

        public IEnumerable SelectComments(int maximumRows, int startRowIndex)
        {
            return RepositoryFactory.Instance.GetCommentRepository().GetByNewsItem(View.NewsItemID).Skip(startRowIndex).Take(maximumRows);
        }

        public int SelectCommentsCount()
        {
            return RepositoryFactory.Instance.GetCommentRepository().GetByNewsItem(View.NewsItemID).Count();
        }

        public void DeleteComment(int commentID)
        {
            RepositoryFactory.Instance.GetCommentRepository().Delete(commentID);

            CacheManager.RemoveLatestComments();

            Context.Response.Redirect(Context.Request.Url.ToString());
        }

    }
}
